package com.xyhy.core.jackson;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.xyhy.core.base.ToolConstant;

public enum JacksonMapper {
  instance;

  public final ObjectMapper objectMapper = JsonMapper.builder()
          .enable(MapperFeature.USE_GETTERS_AS_SETTERS)
          .enable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS)
          .build();

  JacksonMapper() {
    objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));

    objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

    objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

//	objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
    objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

    objectMapper.registerModule(jdk8DateTimeSerialModule());
    objectMapper.registerModule(longSerialModule());

    objectMapper.findAndRegisterModules();

    // objectMapper.addMixIn(HibernateProxy.class, HibernateFilter.class);
  }

  private SimpleModule longSerialModule() {
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
    simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
    return simpleModule;
  }

  private SimpleModule jdk8DateTimeSerialModule() {
    DateTimeFormatter df = DateTimeFormatter.ofPattern(ToolConstant.PATTERN.COMMON);
    JavaTimeModule javaTimeModule = new JavaTimeModule();
    javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(df));
    javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(df));
    return javaTimeModule;
  }

}
